HNOBac Manuscript
  1. Methods
  2. CFUs
  • Introduction
  • Methods
    • RNASeq
    • Cell Counts
    • CFUs
    • LDH
    • Cytokines
    • HEK-Blue
  • References
  • R Session Info

Table of contents

  • Data Input and Selection
    • File Paths
    • Data clean-up
    • Saving files
  • Stats and Plots
    • File Paths
    • Function for each temp condition
    • Apply to each temp

CFUs

library(tidyverse)
library(ggpubr)
library(ggtext)
library(scales)
library(lme4)
library(afex)
library(emmeans)
library(gridExtra)

Data Input and Selection

File Paths

# Folder paths
input_path <- "data/input_data/CFUs/"
metadata_path <- "data/metadata/CFUs"

# Create subfolders for output files
dataframes_folder <- "data/dataframes"
if (!file.exists("data/dataframes")) {
  dir.create("data/dataframes", recursive = TRUE)
}

# Load data and metadata
input_data <- read_csv(file.path(input_path, "HNOBac_CFUs_0130_2024.csv")) %>% mutate_if(is.character, factor)
input_data$Time <- as.factor(input_data$Time)
Bac_order <- read_csv(file.path(metadata_path, "Order_Bacteria_CFUs.csv"))

Data clean-up

# Setting zero values to the limit of detection
CFU_data <- input_data %>%
  mutate(
    LOD = CFUs == 0,
    NewCFU = ifelse(LOD, 3.75, CFUs)
  )

# Factor Ordering and Styling
CFU_data <- CFU_data %>%
  mutate(Combined = interaction(bacteria, Time))
CFU_data <- merge(CFU_data, Bac_order, by = "Combined") 
CFU_data$bacteria_label <- factor(CFU_data$bacteria_label, levels = Bac_order$bacteria_label)
CFU_data$Line <- fct_recode(CFU_data$Line, "HNO918" = "A", "HNO204" = "B", "HNO919" = "C") 

Saving files

# Save data frame as CSV files in the output folder
write_csv(CFU_data, file.path(dataframes_folder, "CFU_values.csv"))

# Save data frame as R objects in the output folder
saveRDS(CFU_data, file.path(dataframes_folder, "CFU_values.rds"))

# Cleaning-up all objects from the environment
rm(list = ls())

# Use this to read the final objects
CFU_data <- readRDS("data/dataframes/CFU_values.rds")

Stats and Plots

File Paths

# Folder paths
dataframes_path <- "data/dataframes"
metadata_path <- "data/metadata/CFUs"

# Create subfolders for output files
figures_folder <- "data/outputs/CFUs/figures"
if (!file.exists("data/outputs/CFUs/figures")) {
  dir.create("data/outputs/CFUs/figures", recursive = TRUE)
}
stats_folder <- "data/outputs/CFUs/stats"
if (!file.exists("data/outputs/CFUs/stats")) {
  dir.create("data/outputs/CFUs/stats", recursive = TRUE)
}

# Load data and metadata
CFU_data <- readRDS("data/dataframes/CFU_values.rds")
Bac_order <- read_csv(file.path(metadata_path, "Order_Bacteria_CFUs.csv"))

Function for each temp condition

# Function to analyze each temp condition
analysis_function <- function(data, each_temp, cutoff_pvalue, cutoff_FC) {
  
  # Subset the data to the selected temp
  data_subset <- data %>%
    filter(Temp == each_temp) 
  
  # Remove time 0h from the stats
  data_stats <- data_subset %>%
    filter(Time != 0)
  
  # Mixed-effects model with random effects
  model <- lmer(log(NewCFU) ~ bacteria * Time 
                + (1|Line) + (1|Line:Date), 
                data = data_stats)
  #Anova
  anova <- anova(model)
  anova_df <- as.data.frame(anova) %>%
    mutate(sign = case_when(
      `Pr(>F)` < cutoff_pvalue ~ "*",
      TRUE ~ "")) %>%
    mutate_if(is.numeric, ~ format(., digits = 2, scientific = TRUE))
  
  # Calculate Individual contrasts
  emmeans_model <- emmeans(model, ~ bacteria * Time)
  emmeans_time <- pairs(emmeans_model, simple = "Time", adjust = "none")    
  
  # Extract random effects and convert to dataframe (if not singular)
  random_effects_df <- as.data.frame(VarCorr(model)) %>%
    mutate(proportion = round(100 * (vcov / sum(vcov)), 2))
  
  # Adds predictions based on fixed effects, averaged over random effects. It gives a population estimate
  data_stats <- cbind(data_stats, predval = predict(model,re.form = NA, se.fit = TRUE))
  data_summary_df <- data_stats %>%
    group_by(Combined, bacteria_label) %>%
    summarize(mean.real = mean(NewCFU),
              mean.predval = mean(predval.fit), 
              mean.predval.se = mean(predval.se.fit)) %>%
    mutate(exp.mean.predval = exp(mean.predval),
           max = exp(mean.predval + 2*mean.predval.se),
           min = exp(mean.predval - 2*mean.predval.se))
  
  # Extract time contrasts from emmeans_model, convert to dataframe and adjust pvalues
  contrasts_time_df <- as.data.frame(summary(emmeans_time)) %>%
    mutate(Temp = each_temp) %>%
    mutate(p.adj.holm = p.adjust(p.value, method = "holm")) %>%
    mutate(sign = case_when(
      p.adj.holm < cutoff_pvalue ~ "*",
      TRUE ~ ""))
  
  # Edits to the contrast dataframe to include pvalue brackets in plot
  contrasts_time_df <- contrasts_time_df %>%
    separate(contrast, into = c("Time1", "Time2"), sep = " - ") %>%
    mutate(Time1 = sub("Time", "", Time1),
           Time2 = sub("Time", "", Time2)) %>%
    mutate(condition1 = paste(bacteria, Time1, sep = "."),
           condition2 = paste(bacteria, Time2, sep = "."))
  
  contrasts_time_df$group1 <- Bac_order$bacteria_label[match(contrasts_time_df$condition1, Bac_order$Combined)]
  contrasts_time_df$group2 <- Bac_order$bacteria_label[match(contrasts_time_df$condition2, Bac_order$Combined)]
  
  # Calculate fold-change values for each contrast
  contrasts_time_df <- contrasts_time_df %>%
    ungroup() %>%
    left_join(select(data_summary_df, Combined, exp.mean.predval), by = join_by(condition1 == Combined)) %>%
    left_join(select(data_summary_df, Combined, exp.mean.predval), by = join_by(condition2 == Combined), suffix = c(".1", ".2")) %>%
    mutate(FC = exp.mean.predval.1 / exp.mean.predval.2,
           FC = if_else(FC < 1, -1 / FC, FC),
           highlighted = case_when(
             FC <= -cutoff_FC ~ "+",
             FC >= cutoff_FC ~ "-",
             TRUE ~ "")) 
  
  # Select p values to plot and define their location
  contrast_sign <- contrasts_time_df %>%
    filter(sign != "" & highlighted != "") %>%
    mutate(p.adj.holm = format(p.adj.holm, digits = 2, scientific = TRUE))
  
  location <- log10(max(data_subset$NewCFU, na.rm = TRUE)) * 1.1
  
  # Standard Boxplot
  plot_1 <- ggplot() +
    geom_boxplot(data = data_subset, aes(x = bacteria_label, y = NewCFU, fill = bacteria_label)) + 
    
    geom_jitter(data = data_subset, aes(x = bacteria_label, y = NewCFU, shape = Line), 
                fill = "grey50", color = "grey30", size = 2, width = 0.05, stroke = 0.75) +
    
    scale_fill_manual(values = c("#AA35E3","#AA35E3","#AA35E3",
                                 "#2e67f2","#2e67f2","#2e67f2", 
                                 "#927ed1","#927ed1","#927ed1")) +
    
    scale_shape_manual(values = c(21, 22, 24)) +
    
    scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
                  labels = trans_format("log10", math_format(10^.x))) +
    labs(x = "Hours post-inoculation",
         y = paste0("CFUs/HNO at ", each_temp, " °C")) +
    theme_bw() +
    theme(panel.grid = element_blank(),
          legend.position = "none",
          text = element_text(size = 20), 
          axis.text.x = element_markdown(), 
          axis.text.y = element_text(color = "black"))
  
  # Plot with predicted means and standard errors of the estimates
  plot_2 <- ggplot() +
    geom_point(data = data_subset, 
                aes(x = bacteria_label, y = NewCFU, fill = bacteria_label, color = bacteria_label, shape = Line, group = Line), 
                position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.2),
                size = 1.5, alpha = 0.75, stroke = 0.75) +

    geom_point(data = data_summary_df, aes(x = bacteria_label, y = exp.mean.predval), shape = 3, size = 3) +
    geom_errorbar(data = data_summary_df, aes(x = bacteria_label,
                                              y = exp.mean.predval,
                                              ymax = max,
                                              ymin = min),
                  width = 0.5) +
    
    scale_fill_manual(values = c("#AA35E3","#AA35E3","#AA35E3","#2e67f2","#2e67f2","#2e67f2","#927ed1","#927ed1","#927ed1")) +
    scale_color_manual(values = c("#AA35E3","#AA35E3","#AA35E3","#2e67f2","#2e67f2","#2e67f2","#927ed1","#927ed1","#927ed1")) +
    scale_shape_manual(values = c(21, 22, 24)) +
    
    scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
                  labels = trans_format("log10", math_format(10^.x)),
                  expand = c(0.1,0)) +
    
    labs(x = "Hours post-inoculation",
         y = paste0("CFUs/HNO at ", each_temp, " °C")) +
    theme_bw() +
    theme(panel.grid = element_blank(), 
          legend.position = "none",
          text = element_text(size = 20), 
          axis.text.x = element_markdown(), 
          axis.text.y = element_text(color = "black"))
  
  # Conditionally add p-value annotations layer
  if (nrow(contrast_sign) > 0) {
    plot_2 <- plot_2 +
      stat_pvalue_manual(contrast_sign, label = "p.adj.holm", y.position = location,
                         tip.length = 0.02, bracket.shorten = 0.2, vjust = -0.2, bracket.size = 0.3, size = 3.5)
  } else {
    plot_2 <- plot_2
  }
  
  # Arrange plot and tables for summary pdf
  table <- contrasts_time_df %>%
    select(condition1, condition2, p.adj.holm, sign, exp.mean.predval.1, exp.mean.predval.2, FC, highlighted) %>%
    mutate(p.adj.holm = format(p.adj.holm, digits = 2, scientific = TRUE))
  
  Tmin <- ttheme_minimal()
  panel <- ggarrange(plot_1 + theme(plot.margin = unit(c(0.25,0.25,0.25,0.25), "in")), 
                     plot_2 + theme(plot.margin = unit(c(0.25,0.25,0.25,0.25), "in")),
                     tableGrob(anova_df, theme = Tmin), 
                     tableGrob(random_effects_df, theme = Tmin, rows = NULL), 
                     tableGrob(table, theme = Tmin, rows = NULL), 
                     ncol = 1, heights = c(0.7, 0.7, 0.2, 0.2, 0.2),
                     labels = c("  Standard Boxplot ", "Predicted Mean ± 2*SE", "    Anova    ", "Random Effects", "   Contrasts  "))
  panel <- annotate_figure(panel, top = text_grob(
    paste0("Analysis for ", each_temp, "C. P-value: ", cutoff_pvalue, " and FC: ", cutoff_FC),
                                                         face = "bold", size = 14, color = "red"))
  
  # Save files
  ggsave(panel, filename = paste0(figures_folder, "/summaryCFU_", each_temp, ".pdf"), width = 10, height = 15)
  ggsave(plot_2, filename = paste0(figures_folder, "/plotCFU_", each_temp, ".png"), width = 7, height = 6)
  saveRDS(plot_2, file.path(figures_folder, paste0("plotCFU_", each_temp, ".rds")))
  write_csv(anova_df, file.path(stats_folder, paste0("anova_", each_temp, ".csv")))
  write_csv(random_effects_df, file.path(stats_folder, paste0("stats_random_effects_", each_temp, ".csv")))
  write_csv(contrasts_time_df, file.path(stats_folder, paste0("stats_contrasts_", each_temp, ".csv")))
  write_csv(data_summary_df, file.path(stats_folder, paste0("stats_summary_", each_temp, ".csv")))
  
  return(list(
    anova = anova_df,
    random_effects = random_effects_df,
    contrasts_time = contrasts_time_df,
    data_summary = data_summary_df,
    data_stats = data_stats,
    plot_1 = plot_1,
    plot_2 = plot_2,
    panel = panel
  ))
}

Apply to each temp

Main Data: 34C

analysis_function(CFU_data, each_temp = "34", cutoff_pvalue = 0.05, cutoff_FC = 1)
$anova
               Sum Sq Mean Sq NumDF   DenDF F value  Pr(>F) sign
bacteria      2.2e+02 1.1e+02     2 8.4e+01 1.0e+01 1.3e-04    *
Time          1.2e+00 1.2e+00     1 7.4e+01 1.1e-01 7.4e-01     
bacteria:Time 4.6e+02 2.3e+02     2 7.4e+01 2.1e+01 4.9e-08    *

$random_effects
        grp        var1 var2      vcov    sdcor proportion
1 Line:Date (Intercept) <NA>  6.414043 2.532596      37.19
2      Line (Intercept) <NA>  0.000000 0.000000       0.00
3  Residual        <NA> <NA> 10.831722 3.291158      62.81

$contrasts_time
  Time1 Time2 bacteria  estimate       SE       df   t.ratio      p.value Temp
1    24    48      Dpi  2.807217 1.097053 73.38104  2.558872 1.256251e-02   34
2    24    48      Sau -5.797778 1.128858 73.38104 -5.135968 2.230214e-06   34
3    24    48      Spn  3.651203 1.163600 73.38104  3.137850 2.450515e-03   34
    p.adj.holm sign condition1 condition2
1 1.256251e-02    *     Dpi.24     Dpi.48
2 6.690641e-06    *     Sau.24     Sau.48
3 4.901030e-03    *     Spn.24     Spn.48
                                         group1
1 <b><span style='color:#0443DC;'>24</span></b>
2 <b><span style='color:#6D05A0;'>24</span></b>
3 <b><span style='color:#927ED1;'>24</span></b>
                                         group2 exp.mean.predval.1
1 <b><span style='color:#0443DC;'>48</span></b>           54171.03
2 <b><span style='color:#6D05A0;'>48</span></b>           28289.45
3 <b><span style='color:#927ED1;'>48</span></b>         1216148.62
  exp.mean.predval.2         FC highlighted
1           3270.455   16.56376           -
2        9323251.362 -329.56637           +
3          31571.076   38.52097           -

$data_summary
# A tibble: 6 × 8
# Groups:   Combined [6]
  Combined bacteria_label                 mean.real mean.predval mean.predval.se
  <fct>    <fct>                              <dbl>        <dbl>           <dbl>
1 Dpi.24   <b><span style='color:#0443DC…    3.81e5        10.9            0.951
2 Sau.24   <b><span style='color:#6D05A0…    4.42e6        10.3            0.973
3 Spn.24   <b><span style='color:#927ED1…    1.04e7        14.0            0.998
4 Dpi.48   <b><span style='color:#0443DC…    8.63e4         8.09           0.951
5 Sau.48   <b><span style='color:#6D05A0…    1.36e8        16.0            0.973
6 Spn.48   <b><span style='color:#927ED1…    1.34e7        10.4            0.998
# ℹ 3 more variables: exp.mean.predval <dbl>, max <dbl>, min <dbl>

$data_stats
    Combined     Date   Line Temp Time bacteria Strain        CFUs   LOD
1     Dpi.24  2/14/23 HNO919   34   24      Dpi   3065 1.31250e+06 FALSE
2     Dpi.24   2/7/23 HNO204   34   24      Dpi   3065 1.98750e+03 FALSE
3     Dpi.24   9/7/22 HNO918   34   24      Dpi   3065 6.26250e+05 FALSE
4     Dpi.24  11/2/22 HNO919   34   24      Dpi   3065 1.01250e+03 FALSE
5     Dpi.24  8/16/22 HNO919   34   24      Dpi   3065 9.11250e+04 FALSE
6     Dpi.24  1/17/23 HNO204   34   24      Dpi   3065 1.05000e+03 FALSE
7     Dpi.24   8/9/22 HNO918   34   24      Dpi   3065 8.25000e+05 FALSE
8     Dpi.24  8/10/22 HNO204   34   24      Dpi   3065 4.83750e+05 FALSE
9     Dpi.24  9/14/22 HNO919   34   24      Dpi   3065 5.13750e+04 FALSE
10    Dpi.24  8/23/22 HNO204   34   24      Dpi   3065 1.91250e+06 FALSE
11    Dpi.24  11/1/22 HNO919   34   24      Dpi   3065 4.12500e+05 FALSE
12    Dpi.24  8/31/22 HNO204   34   24      Dpi   3065 1.46250e+04 FALSE
13    Dpi.24  1/24/23 HNO919   34   24      Dpi   3065 9.00000e+05 FALSE
14    Dpi.24  2/28/23 HNO204   34   24      Dpi   3065 8.25000e+03 FALSE
15    Dpi.24  8/30/22 HNO918   34   24      Dpi   3065 2.36250e+03 FALSE
16    Dpi.24  8/17/22 HNO918   34   24      Dpi   3065 3.30000e+04 FALSE
17    Dpi.24  9/13/22 HNO204   34   24      Dpi   3065 9.60000e+01 FALSE
18    Dpi.24   9/6/22 HNO919   34   24      Dpi   3065 1.83750e+05 FALSE
19    Dpi.48  2/14/23 HNO919   34   48      Dpi   3065 2.77500e+04 FALSE
20    Dpi.48   9/7/22 HNO918   34   48      Dpi   3065 3.78000e+02 FALSE
21    Dpi.48  8/16/22 HNO919   34   48      Dpi   3065 7.80000e+03 FALSE
22    Dpi.48   2/7/23 HNO204   34   48      Dpi   3065 1.95000e+02 FALSE
23    Dpi.48  1/17/23 HNO204   34   48      Dpi   3065 0.00000e+00  TRUE
24    Dpi.48  8/23/22 HNO204   34   48      Dpi   3065 6.33750e+05 FALSE
25    Dpi.48  9/14/22 HNO919   34   48      Dpi   3065 6.45000e+04 FALSE
26    Dpi.48  11/1/22 HNO919   34   48      Dpi   3065 3.67500e+04 FALSE
27    Dpi.48  11/2/22 HNO919   34   48      Dpi   3065 2.55000e+02 FALSE
28    Dpi.48  2/28/23 HNO204   34   48      Dpi   3065 9.00000e+01 FALSE
29    Dpi.48  9/13/22 HNO204   34   48      Dpi   3065 0.00000e+00  TRUE
30    Dpi.48  8/10/22 HNO204   34   48      Dpi   3065 6.18750e+05 FALSE
31    Dpi.48   8/9/22 HNO918   34   48      Dpi   3065 2.47500e+04 FALSE
32    Dpi.48   9/6/22 HNO919   34   48      Dpi   3065 2.02500e+02 FALSE
33    Dpi.48  8/31/22 HNO204   34   48      Dpi   3065 1.20000e+05 FALSE
34    Dpi.48  8/30/22 HNO918   34   48      Dpi   3065 1.31250e+03 FALSE
35    Dpi.48  1/24/23 HNO919   34   48      Dpi   3065 1.61250e+04 FALSE
36    Dpi.48  8/17/22 HNO918   34   48      Dpi   3065 7.12500e+02 FALSE
37    Sau.24  8/17/22 HNO918   34   24      Sau   2115 1.08750e+03 FALSE
38    Sau.24   2/7/23 HNO204   34   24      Sau   2115 0.00000e+00  TRUE
39    Sau.24 10/11/22 HNO204   34   24      Sau   2115 2.85000e+06 FALSE
40    Sau.24  9/27/22 HNO919   34   24      Sau   2115 2.55000e+03 FALSE
41    Sau.24  8/30/22 HNO918   34   24      Sau   2115 1.95000e+05 FALSE
42    Sau.24  10/4/22 HNO918   34   24      Sau   2115 1.68750e+04 FALSE
43    Sau.24  8/31/22 HNO204   34   24      Sau   2115 9.75000e+04 FALSE
44    Sau.24   9/6/22 HNO919   34   24      Sau   2115 7.12500e+03 FALSE
45    Sau.24  9/14/22 HNO919   34   24      Sau   2115 8.62500e+03 FALSE
46    Sau.24  8/16/22 HNO919   34   24      Sau   2115 1.53750e+03 FALSE
47    Sau.24  2/28/23 HNO204   34   24      Sau   2115 4.57500e+05 FALSE
48    Sau.24 10/25/22 HNO204   34   24      Sau   2115 4.68750e+04 FALSE
49    Sau.24  9/21/22 HNO204   34   24      Sau   2115 2.32500e+03 FALSE
50    Sau.24  9/20/22 HNO918   34   24      Sau   2115 1.68750e+03 FALSE
51    Sau.24  2/14/23 HNO919   34   24      Sau   2115 2.70000e+04 FALSE
52    Sau.24   9/7/22 HNO918   34   24      Sau   2115 7.12500e+07 FALSE
53    Sau.24  1/17/23 HNO204   34   24      Sau   2115 1.61250e+05 FALSE
54    Sau.48  8/17/22 HNO918   34   48      Sau   2115 1.50000e+08 FALSE
55    Sau.48   9/6/22 HNO919   34   48      Sau   2115 1.46250e+04 FALSE
56    Sau.48  8/16/22 HNO919   34   48      Sau   2115 2.47500e+05 FALSE
57    Sau.48   2/7/23 HNO204   34   48      Sau   2115 1.01250e+08 FALSE
58    Sau.48  8/30/22 HNO918   34   48      Sau   2115 5.77500e+06 FALSE
59    Sau.48  9/14/22 HNO919   34   48      Sau   2115 3.86250e+05 FALSE
60    Sau.48  10/4/22 HNO918   34   48      Sau   2115 1.31250e+08 FALSE
61    Sau.48  1/17/23 HNO204   34   48      Sau   2115 1.65000e+06 FALSE
62    Sau.48 10/11/22 HNO204   34   48      Sau   2115 3.90000e+08 FALSE
63    Sau.48  8/31/22 HNO204   34   48      Sau   2115 1.27500e+08 FALSE
64    Sau.48  2/14/23 HNO919   34   48      Sau   2115 1.05000e+06 FALSE
65    Sau.48 10/25/22 HNO204   34   48      Sau   2115 6.26250e+06 FALSE
66    Sau.48  9/20/22 HNO918   34   48      Sau   2115 1.05000e+09 FALSE
67    Sau.48  9/21/22 HNO204   34   48      Sau   2115 2.66250e+04 FALSE
68    Sau.48  9/27/22 HNO919   34   48      Sau   2115 1.35000e+08 FALSE
69    Sau.48  2/28/23 HNO204   34   48      Sau   2115 2.10000e+04 FALSE
70    Sau.48   9/7/22 HNO918   34   48      Sau   2115 2.17500e+08 FALSE
71    Spn.24  8/10/22 HNO204   34   24      Spn   1906 1.22625e+07 FALSE
72    Spn.24  1/24/23 HNO919   34   24      Spn   1906 5.58750e+06 FALSE
73    Spn.24  9/13/22 HNO204   34   24      Spn   1906 2.40000e+04 FALSE
74    Spn.24   8/9/22 HNO918   34   24      Spn   1906 2.52750e+07 FALSE
75    Spn.24  8/23/22 HNO204   34   24      Spn   1906 1.65750e+07 FALSE
76    Spn.24   2/7/23 HNO204   34   24      Spn   1906 9.75000e+06 FALSE
77    Spn.24  8/31/22 HNO204   34   24      Spn   1906 1.80000e+04 FALSE
78    Spn.24  1/17/23 HNO204   34   24      Spn   1906 3.30000e+06 FALSE
79    Spn.24  2/28/23 HNO204   34   24      Spn   1906 6.71250e+04 FALSE
80    Spn.24  9/14/22 HNO919   34   24      Spn   1906 5.73750e+05 FALSE
81    Spn.24  8/30/22 HNO918   34   24      Spn   1906 2.36250e+05 FALSE
82    Spn.24  2/14/23 HNO919   34   24      Spn   1906 3.30000e+07 FALSE
83    Spn.24  9/27/22 HNO919   34   24      Spn   1906 2.92500e+07 FALSE
84    Spn.24   9/6/22 HNO919   34   24      Spn   1906 9.03750e+04 FALSE
85    Spn.24  10/4/22 HNO918   34   24      Spn   1906 3.03750e+07 FALSE
86    Spn.24 10/11/22 HNO204   34   24      Spn   1906 1.23750e+04 FALSE
87    Spn.48  8/10/22 HNO204   34   48      Spn   1906 1.53750e+07 FALSE
88    Spn.48  1/24/23 HNO919   34   48      Spn   1906 1.35000e+06 FALSE
89    Spn.48  9/13/22 HNO204   34   48      Spn   1906 0.00000e+00  TRUE
90    Spn.48  8/23/22 HNO204   34   48      Spn   1906 3.78750e+07 FALSE
91    Spn.48  1/17/23 HNO204   34   48      Spn   1906 0.00000e+00  TRUE
92    Spn.48   8/9/22 HNO918   34   48      Spn   1906 6.15000e+07 FALSE
93    Spn.48  8/31/22 HNO204   34   48      Spn   1906 6.78750e+04 FALSE
94    Spn.48   9/6/22 HNO919   34   48      Spn   1906 5.55000e+01 FALSE
95    Spn.48   2/7/23 HNO204   34   48      Spn   1906 0.00000e+00  TRUE
96    Spn.48  2/28/23 HNO204   34   48      Spn   1906 1.03875e+04 FALSE
97    Spn.48  10/4/22 HNO918   34   48      Spn   1906 6.41250e+07 FALSE
98    Spn.48  9/14/22 HNO919   34   48      Spn   1906 6.75000e+02 FALSE
99    Spn.48  2/14/23 HNO919   34   48      Spn   1906 5.73750e+06 FALSE
100   Spn.48  9/27/22 HNO919   34   48      Spn   1906 2.55000e+07 FALSE
101   Spn.48 10/11/22 HNO204   34   48      Spn   1906 2.13750e+06 FALSE
102   Spn.48  8/30/22 HNO918   34   48      Spn   1906 0.00000e+00  TRUE
         NewCFU                                bacteria_label predval.fit
1   1.31250e+06 <b><span style='color:#0443DC;'>24</span></b>   10.899902
2   1.98750e+03 <b><span style='color:#0443DC;'>24</span></b>   10.899902
3   6.26250e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
4   1.01250e+03 <b><span style='color:#0443DC;'>24</span></b>   10.899902
5   9.11250e+04 <b><span style='color:#0443DC;'>24</span></b>   10.899902
6   1.05000e+03 <b><span style='color:#0443DC;'>24</span></b>   10.899902
7   8.25000e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
8   4.83750e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
9   5.13750e+04 <b><span style='color:#0443DC;'>24</span></b>   10.899902
10  1.91250e+06 <b><span style='color:#0443DC;'>24</span></b>   10.899902
11  4.12500e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
12  1.46250e+04 <b><span style='color:#0443DC;'>24</span></b>   10.899902
13  9.00000e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
14  8.25000e+03 <b><span style='color:#0443DC;'>24</span></b>   10.899902
15  2.36250e+03 <b><span style='color:#0443DC;'>24</span></b>   10.899902
16  3.30000e+04 <b><span style='color:#0443DC;'>24</span></b>   10.899902
17  9.60000e+01 <b><span style='color:#0443DC;'>24</span></b>   10.899902
18  1.83750e+05 <b><span style='color:#0443DC;'>24</span></b>   10.899902
19  2.77500e+04 <b><span style='color:#0443DC;'>48</span></b>    8.092684
20  3.78000e+02 <b><span style='color:#0443DC;'>48</span></b>    8.092684
21  7.80000e+03 <b><span style='color:#0443DC;'>48</span></b>    8.092684
22  1.95000e+02 <b><span style='color:#0443DC;'>48</span></b>    8.092684
23  3.75000e+00 <b><span style='color:#0443DC;'>48</span></b>    8.092684
24  6.33750e+05 <b><span style='color:#0443DC;'>48</span></b>    8.092684
25  6.45000e+04 <b><span style='color:#0443DC;'>48</span></b>    8.092684
26  3.67500e+04 <b><span style='color:#0443DC;'>48</span></b>    8.092684
27  2.55000e+02 <b><span style='color:#0443DC;'>48</span></b>    8.092684
28  9.00000e+01 <b><span style='color:#0443DC;'>48</span></b>    8.092684
29  3.75000e+00 <b><span style='color:#0443DC;'>48</span></b>    8.092684
30  6.18750e+05 <b><span style='color:#0443DC;'>48</span></b>    8.092684
31  2.47500e+04 <b><span style='color:#0443DC;'>48</span></b>    8.092684
32  2.02500e+02 <b><span style='color:#0443DC;'>48</span></b>    8.092684
33  1.20000e+05 <b><span style='color:#0443DC;'>48</span></b>    8.092684
34  1.31250e+03 <b><span style='color:#0443DC;'>48</span></b>    8.092684
35  1.61250e+04 <b><span style='color:#0443DC;'>48</span></b>    8.092684
36  7.12500e+02 <b><span style='color:#0443DC;'>48</span></b>    8.092684
37  1.08750e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
38  3.75000e+00 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
39  2.85000e+06 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
40  2.55000e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
41  1.95000e+05 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
42  1.68750e+04 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
43  9.75000e+04 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
44  7.12500e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
45  8.62500e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
46  1.53750e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
47  4.57500e+05 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
48  4.68750e+04 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
49  2.32500e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
50  1.68750e+03 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
51  2.70000e+04 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
52  7.12500e+07 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
53  1.61250e+05 <b><span style='color:#6D05A0;'>24</span></b>   10.250244
54  1.50000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
55  1.46250e+04 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
56  2.47500e+05 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
57  1.01250e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
58  5.77500e+06 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
59  3.86250e+05 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
60  1.31250e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
61  1.65000e+06 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
62  3.90000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
63  1.27500e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
64  1.05000e+06 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
65  6.26250e+06 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
66  1.05000e+09 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
67  2.66250e+04 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
68  1.35000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
69  2.10000e+04 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
70  2.17500e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.048022
71  1.22625e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
72  5.58750e+06 <b><span style='color:#927ED1;'>24</span></b>   14.011200
73  2.40000e+04 <b><span style='color:#927ED1;'>24</span></b>   14.011200
74  2.52750e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
75  1.65750e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
76  9.75000e+06 <b><span style='color:#927ED1;'>24</span></b>   14.011200
77  1.80000e+04 <b><span style='color:#927ED1;'>24</span></b>   14.011200
78  3.30000e+06 <b><span style='color:#927ED1;'>24</span></b>   14.011200
79  6.71250e+04 <b><span style='color:#927ED1;'>24</span></b>   14.011200
80  5.73750e+05 <b><span style='color:#927ED1;'>24</span></b>   14.011200
81  2.36250e+05 <b><span style='color:#927ED1;'>24</span></b>   14.011200
82  3.30000e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
83  2.92500e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
84  9.03750e+04 <b><span style='color:#927ED1;'>24</span></b>   14.011200
85  3.03750e+07 <b><span style='color:#927ED1;'>24</span></b>   14.011200
86  1.23750e+04 <b><span style='color:#927ED1;'>24</span></b>   14.011200
87  1.53750e+07 <b><span style='color:#927ED1;'>48</span></b>   10.359997
88  1.35000e+06 <b><span style='color:#927ED1;'>48</span></b>   10.359997
89  3.75000e+00 <b><span style='color:#927ED1;'>48</span></b>   10.359997
90  3.78750e+07 <b><span style='color:#927ED1;'>48</span></b>   10.359997
91  3.75000e+00 <b><span style='color:#927ED1;'>48</span></b>   10.359997
92  6.15000e+07 <b><span style='color:#927ED1;'>48</span></b>   10.359997
93  6.78750e+04 <b><span style='color:#927ED1;'>48</span></b>   10.359997
94  5.55000e+01 <b><span style='color:#927ED1;'>48</span></b>   10.359997
95  3.75000e+00 <b><span style='color:#927ED1;'>48</span></b>   10.359997
96  1.03875e+04 <b><span style='color:#927ED1;'>48</span></b>   10.359997
97  6.41250e+07 <b><span style='color:#927ED1;'>48</span></b>   10.359997
98  6.75000e+02 <b><span style='color:#927ED1;'>48</span></b>   10.359997
99  5.73750e+06 <b><span style='color:#927ED1;'>48</span></b>   10.359997
100 2.55000e+07 <b><span style='color:#927ED1;'>48</span></b>   10.359997
101 2.13750e+06 <b><span style='color:#927ED1;'>48</span></b>   10.359997
102 3.75000e+00 <b><span style='color:#927ED1;'>48</span></b>   10.359997
    predval.se.fit
1        0.9512642
2        0.9512642
3        0.9512642
4        0.9512642
5        0.9512642
6        0.9512642
7        0.9512642
8        0.9512642
9        0.9512642
10       0.9512642
11       0.9512642
12       0.9512642
13       0.9512642
14       0.9512642
15       0.9512642
16       0.9512642
17       0.9512642
18       0.9512642
19       0.9512642
20       0.9512642
21       0.9512642
22       0.9512642
23       0.9512642
24       0.9512642
25       0.9512642
26       0.9512642
27       0.9512642
28       0.9512642
29       0.9512642
30       0.9512642
31       0.9512642
32       0.9512642
33       0.9512642
34       0.9512642
35       0.9512642
36       0.9512642
37       0.9725831
38       0.9725831
39       0.9725831
40       0.9725831
41       0.9725831
42       0.9725831
43       0.9725831
44       0.9725831
45       0.9725831
46       0.9725831
47       0.9725831
48       0.9725831
49       0.9725831
50       0.9725831
51       0.9725831
52       0.9725831
53       0.9725831
54       0.9725831
55       0.9725831
56       0.9725831
57       0.9725831
58       0.9725831
59       0.9725831
60       0.9725831
61       0.9725831
62       0.9725831
63       0.9725831
64       0.9725831
65       0.9725831
66       0.9725831
67       0.9725831
68       0.9725831
69       0.9725831
70       0.9725831
71       0.9982937
72       0.9982937
73       0.9982937
74       0.9982937
75       0.9982937
76       0.9982937
77       0.9982937
78       0.9982937
79       0.9982937
80       0.9982937
81       0.9982937
82       0.9982937
83       0.9982937
84       0.9982937
85       0.9982937
86       0.9982937
87       0.9982937
88       0.9982937
89       0.9982937
90       0.9982937
91       0.9982937
92       0.9982937
93       0.9982937
94       0.9982937
95       0.9982937
96       0.9982937
97       0.9982937
98       0.9982937
99       0.9982937
100      0.9982937
101      0.9982937
102      0.9982937

$plot_1


$plot_2


$panel

Supplemental Data: 37C

analysis_function(CFU_data, each_temp = "37", cutoff_pvalue = 0.05, cutoff_FC = 1)
$anova
               Sum Sq Mean Sq NumDF   DenDF F value  Pr(>F) sign
bacteria      3.4e+02 1.7e+02     2 5.8e+01 1.2e+01 4.5e-05    *
Time          3.0e-02 3.0e-02     1 4.4e+01 2.1e-03 9.6e-01     
bacteria:Time 2.4e+02 1.2e+02     2 4.4e+01 8.4e+00 7.8e-04    *

$random_effects
        grp        var1 var2      vcov    sdcor proportion
1 Line:Date (Intercept) <NA>  7.890447 2.808994      35.99
2      Line (Intercept) <NA>  0.000000 0.000000       0.00
3  Residual        <NA> <NA> 14.034296 3.746238      64.01

$contrasts_time
  Time1 Time2 bacteria  estimate       SE       df   t.ratio     p.value Temp
1    24    48      Dpi  5.003889 1.529395 44.47372  3.271809 0.002069846   37
2    24    48      Sau -3.851043 1.597401 44.47372 -2.410818 0.020113866   37
3    24    48      Spn -1.027038 1.597401 44.47372 -0.642943 0.523562322   37
   p.adj.holm sign condition1 condition2
1 0.006209537    *     Dpi.24     Dpi.48
2 0.040227732    *     Sau.24     Sau.48
3 0.523562322          Spn.24     Spn.48
                                         group1
1 <b><span style='color:#0443DC;'>24</span></b>
2 <b><span style='color:#6D05A0;'>24</span></b>
3 <b><span style='color:#927ED1;'>24</span></b>
                                         group2 exp.mean.predval.1
1 <b><span style='color:#0443DC;'>48</span></b>            47592.1
2 <b><span style='color:#6D05A0;'>48</span></b>           294997.5
3 <b><span style='color:#927ED1;'>48</span></b>           109063.3
  exp.mean.predval.2         FC highlighted
1       3.194285e+02 148.991409           -
2       1.387730e+07 -47.042095           +
3       3.045900e+05  -2.792781           +

$data_summary
# A tibble: 6 × 8
# Groups:   Combined [6]
  Combined bacteria_label                 mean.real mean.predval mean.predval.se
  <fct>    <fct>                              <dbl>        <dbl>           <dbl>
1 Dpi.24   <b><span style='color:#0443DC…    2.36e5        10.8             1.31
2 Sau.24   <b><span style='color:#6D05A0…    1.91e7        12.6             1.36
3 Spn.24   <b><span style='color:#927ED1…    1.79e7        11.6             1.35
4 Dpi.48   <b><span style='color:#0443DC…    1.23e4         5.77            1.31
5 Sau.48   <b><span style='color:#6D05A0…    1.36e8        16.4             1.36
6 Spn.48   <b><span style='color:#927ED1…    2.90e7        12.6             1.35
# ℹ 3 more variables: exp.mean.predval <dbl>, max <dbl>, min <dbl>

$data_stats
   Combined     Date   Line Temp Time bacteria Strain         CFUs   LOD
1    Dpi.24  9/13/22 HNO204   37   24      Dpi   3065 3.487500e+03 FALSE
2    Dpi.24  11/1/22 HNO919   37   24      Dpi   3065 7.875000e+04 FALSE
3    Dpi.24  8/23/22 HNO204   37   24      Dpi   3065 1.050000e+06 FALSE
4    Dpi.24  9/14/22 HNO919   37   24      Dpi   3065 4.875000e+05 FALSE
5    Dpi.24   9/7/22 HNO918   37   24      Dpi   3065 4.012500e+05 FALSE
6    Dpi.24  8/31/22 HNO204   37   24      Dpi   3065 7.125000e+04 FALSE
7    Dpi.24  8/10/22 HNO204   37   24      Dpi   3065 4.650000e+05 FALSE
8    Dpi.24   8/9/22 HNO918   37   24      Dpi   3065 2.100000e+05 FALSE
9    Dpi.24  8/30/22 HNO918   37   24      Dpi   3065 3.375000e+02 FALSE
10   Dpi.24  11/2/22 HNO919   37   24      Dpi   3065 0.000000e+00  TRUE
11   Dpi.24  8/17/22 HNO918   37   24      Dpi   3065 3.450000e+04 FALSE
12   Dpi.24   9/6/22 HNO919   37   24      Dpi   3065 3.525000e+04 FALSE
13   Dpi.48  9/14/22 HNO919   37   48      Dpi   3065 1.237500e+03 FALSE
14   Dpi.48  11/1/22 HNO919   37   48      Dpi   3065 1.875000e+01 FALSE
15   Dpi.48  8/10/22 HNO204   37   48      Dpi   3065 1.080000e+05 FALSE
16   Dpi.48  9/13/22 HNO204   37   48      Dpi   3065 0.000000e+00  TRUE
17   Dpi.48   9/7/22 HNO918   37   48      Dpi   3065 1.500000e+01 FALSE
18   Dpi.48  8/23/22 HNO204   37   48      Dpi   3065 1.012500e+03 FALSE
19   Dpi.48   8/9/22 HNO918   37   48      Dpi   3065 3.412500e+04 FALSE
20   Dpi.48  8/30/22 HNO918   37   48      Dpi   3065 6.000000e+01 FALSE
21   Dpi.48  8/31/22 HNO204   37   48      Dpi   3065 2.925000e+03 FALSE
22   Dpi.48  11/2/22 HNO919   37   48      Dpi   3065 0.000000e+00  TRUE
23   Dpi.48  8/17/22 HNO918   37   48      Dpi   3065 7.500000e+01 FALSE
24   Dpi.48   9/6/22 HNO919   37   48      Dpi   3065 2.100000e+01 FALSE
25   Sau.24  9/20/22 HNO918   37   24      Sau   2115 1.125000e+07 FALSE
26   Sau.24  2/28/23 HNO204   37   24      Sau   2115 3.562500e+05 FALSE
27   Sau.24  10/4/22 HNO918   37   24      Sau   2115 1.012500e+06 FALSE
28   Sau.24  8/17/22 HNO918   37   24      Sau   2115 1.050000e+06 FALSE
29   Sau.24 10/11/22 HNO204   37   24      Sau   2115 1.575000e+07 FALSE
30   Sau.24   9/6/22 HNO919   37   24      Sau   2115 4.275000e+03 FALSE
31   Sau.24  9/27/22 HNO919   37   24      Sau   2115 3.937500e+04 FALSE
32   Sau.24 10/25/22 HNO204   37   24      Sau   2115 1.800000e+08 FALSE
33   Sau.24  9/21/22 HNO204   37   24      Sau   2115 2.512500e+02 FALSE
34   Sau.24  8/30/22 HNO918   37   24      Sau   2115 6.187500e+05 FALSE
35   Sau.24  9/14/22 HNO919   37   24      Sau   2115 8.250000e+03 FALSE
36   Sau.48 10/11/22 HNO204   37   48      Sau   2115 2.700000e+07 FALSE
37   Sau.48  9/27/22 HNO919   37   48      Sau   2115 1.162500e+08 FALSE
38   Sau.48  2/28/23 HNO204   37   48      Sau   2115 1.200000e+05 FALSE
39   Sau.48  8/17/22 HNO918   37   48      Sau   2115 1.762500e+07 FALSE
40   Sau.48  10/4/22 HNO918   37   48      Sau   2115 4.875000e+08 FALSE
41   Sau.48  8/30/22 HNO918   37   48      Sau   2115 6.112500e+07 FALSE
42   Sau.48  9/20/22 HNO918   37   48      Sau   2115 1.987500e+06 FALSE
43   Sau.48 10/25/22 HNO204   37   48      Sau   2115 4.575000e+08 FALSE
44   Sau.48   9/6/22 HNO919   37   48      Sau   2115 4.875000e+03 FALSE
45   Sau.48  9/14/22 HNO919   37   48      Sau   2115 3.000000e+08 FALSE
46   Sau.48  9/21/22 HNO204   37   48      Sau   2115 2.475000e+07 FALSE
47   Spn.24  8/23/22 HNO204   37   24      Spn   1906 4.387500e+07 FALSE
48   Spn.24  8/10/22 HNO204   37   24      Spn   1906 1.027500e+07 FALSE
49   Spn.24  9/13/22 HNO204   37   24      Spn   1906 1.537500e+03 FALSE
50   Spn.24  8/31/22 HNO204   37   24      Spn   1906 0.000000e+00  TRUE
51   Spn.24 10/11/22 HNO204   37   24      Spn   1906 2.812500e+07 FALSE
52   Spn.24   8/9/22 HNO918   37   24      Spn   1906 1.950000e+07 FALSE
53   Spn.24  8/17/22 HNO918   37   24      Spn   1906 4.500000e+01 FALSE
54   Spn.24   9/6/22 HNO919   37   24      Spn   1906 2.887500e+03 FALSE
55   Spn.24  10/4/22 HNO918   37   24      Spn   1906 4.312500e+07 FALSE
56   Spn.24  9/27/22 HNO919   37   24      Spn   1906 5.250000e+07 FALSE
57   Spn.24  8/30/22 HNO918   37   24      Spn   1906 2.887500e+03 FALSE
58   Spn.48 10/11/22 HNO204   37   48      Spn   1906 3.065625e+02 FALSE
59   Spn.48  8/17/22 HNO918   37   48      Spn   1906 2.025000e+05 FALSE
60   Spn.48  8/10/22 HNO204   37   48      Spn   1906 4.800000e+06 FALSE
61   Spn.48  8/31/22 HNO204   37   48      Spn   1906 7.800000e+07 FALSE
62   Spn.48  10/4/22 HNO918   37   48      Spn   1906 7.200000e+07 FALSE
63   Spn.48  8/30/22 HNO918   37   48      Spn   1906 1.875000e+06 FALSE
64   Spn.48  9/13/22 HNO204   37   48      Spn   1906 0.000000e+00  TRUE
65   Spn.48   9/6/22 HNO919   37   48      Spn   1906 6.900000e+01 FALSE
66   Spn.48  8/23/22 HNO204   37   48      Spn   1906 4.687500e+07 FALSE
67   Spn.48  9/27/22 HNO919   37   48      Spn   1906 3.000000e+07 FALSE
68   Spn.48   8/9/22 HNO918   37   48      Spn   1906 8.550000e+07 FALSE
         NewCFU                                bacteria_label predval.fit
1  3.487500e+03 <b><span style='color:#0443DC;'>24</span></b>   10.770422
2  7.875000e+04 <b><span style='color:#0443DC;'>24</span></b>   10.770422
3  1.050000e+06 <b><span style='color:#0443DC;'>24</span></b>   10.770422
4  4.875000e+05 <b><span style='color:#0443DC;'>24</span></b>   10.770422
5  4.012500e+05 <b><span style='color:#0443DC;'>24</span></b>   10.770422
6  7.125000e+04 <b><span style='color:#0443DC;'>24</span></b>   10.770422
7  4.650000e+05 <b><span style='color:#0443DC;'>24</span></b>   10.770422
8  2.100000e+05 <b><span style='color:#0443DC;'>24</span></b>   10.770422
9  3.375000e+02 <b><span style='color:#0443DC;'>24</span></b>   10.770422
10 3.750000e+00 <b><span style='color:#0443DC;'>24</span></b>   10.770422
11 3.450000e+04 <b><span style='color:#0443DC;'>24</span></b>   10.770422
12 3.525000e+04 <b><span style='color:#0443DC;'>24</span></b>   10.770422
13 1.237500e+03 <b><span style='color:#0443DC;'>48</span></b>    5.766533
14 1.875000e+01 <b><span style='color:#0443DC;'>48</span></b>    5.766533
15 1.080000e+05 <b><span style='color:#0443DC;'>48</span></b>    5.766533
16 3.750000e+00 <b><span style='color:#0443DC;'>48</span></b>    5.766533
17 1.500000e+01 <b><span style='color:#0443DC;'>48</span></b>    5.766533
18 1.012500e+03 <b><span style='color:#0443DC;'>48</span></b>    5.766533
19 3.412500e+04 <b><span style='color:#0443DC;'>48</span></b>    5.766533
20 6.000000e+01 <b><span style='color:#0443DC;'>48</span></b>    5.766533
21 2.925000e+03 <b><span style='color:#0443DC;'>48</span></b>    5.766533
22 3.750000e+00 <b><span style='color:#0443DC;'>48</span></b>    5.766533
23 7.500000e+01 <b><span style='color:#0443DC;'>48</span></b>    5.766533
24 2.100000e+01 <b><span style='color:#0443DC;'>48</span></b>    5.766533
25 1.125000e+07 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
26 3.562500e+05 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
27 1.012500e+06 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
28 1.050000e+06 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
29 1.575000e+07 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
30 4.275000e+03 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
31 3.937500e+04 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
32 1.800000e+08 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
33 2.512500e+02 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
34 6.187500e+05 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
35 8.250000e+03 <b><span style='color:#6D05A0;'>24</span></b>   12.594722
36 2.700000e+07 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
37 1.162500e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
38 1.200000e+05 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
39 1.762500e+07 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
40 4.875000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
41 6.112500e+07 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
42 1.987500e+06 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
43 4.575000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
44 4.875000e+03 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
45 3.000000e+08 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
46 2.475000e+07 <b><span style='color:#6D05A0;'>48</span></b>   16.445765
47 4.387500e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
48 1.027500e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
49 1.537500e+03 <b><span style='color:#927ED1;'>24</span></b>   11.599684
50 3.750000e+00 <b><span style='color:#927ED1;'>24</span></b>   11.599684
51 2.812500e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
52 1.950000e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
53 4.500000e+01 <b><span style='color:#927ED1;'>24</span></b>   11.599684
54 2.887500e+03 <b><span style='color:#927ED1;'>24</span></b>   11.599684
55 4.312500e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
56 5.250000e+07 <b><span style='color:#927ED1;'>24</span></b>   11.599684
57 2.887500e+03 <b><span style='color:#927ED1;'>24</span></b>   11.599684
58 3.065625e+02 <b><span style='color:#927ED1;'>48</span></b>   12.626722
59 2.025000e+05 <b><span style='color:#927ED1;'>48</span></b>   12.626722
60 4.800000e+06 <b><span style='color:#927ED1;'>48</span></b>   12.626722
61 7.800000e+07 <b><span style='color:#927ED1;'>48</span></b>   12.626722
62 7.200000e+07 <b><span style='color:#927ED1;'>48</span></b>   12.626722
63 1.875000e+06 <b><span style='color:#927ED1;'>48</span></b>   12.626722
64 3.750000e+00 <b><span style='color:#927ED1;'>48</span></b>   12.626722
65 6.900000e+01 <b><span style='color:#927ED1;'>48</span></b>   12.626722
66 4.687500e+07 <b><span style='color:#927ED1;'>48</span></b>   12.626722
67 3.000000e+07 <b><span style='color:#927ED1;'>48</span></b>   12.626722
68 8.550000e+07 <b><span style='color:#927ED1;'>48</span></b>   12.626722
   predval.se.fit
1        1.306561
2        1.306561
3        1.306561
4        1.306561
5        1.306561
6        1.306561
7        1.306561
8        1.306561
9        1.306561
10       1.306561
11       1.306561
12       1.306561
13       1.306561
14       1.306561
15       1.306561
16       1.306561
17       1.306561
18       1.306561
19       1.306561
20       1.306561
21       1.306561
22       1.306561
23       1.306561
24       1.306561
25       1.355826
26       1.355826
27       1.355826
28       1.355826
29       1.355826
30       1.355826
31       1.355826
32       1.355826
33       1.355826
34       1.355826
35       1.355826
36       1.355826
37       1.355826
38       1.355826
39       1.355826
40       1.355826
41       1.355826
42       1.355826
43       1.355826
44       1.355826
45       1.355826
46       1.355826
47       1.351123
48       1.351123
49       1.351123
50       1.351123
51       1.351123
52       1.351123
53       1.351123
54       1.351123
55       1.351123
56       1.351123
57       1.351123
58       1.351123
59       1.351123
60       1.351123
61       1.351123
62       1.351123
63       1.351123
64       1.351123
65       1.351123
66       1.351123
67       1.351123
68       1.351123

$plot_1


$plot_2


$panel

Merged Files

pdf_output <- file.path(figures_folder, "HNOBac_SummaryCFUs.pdf")

# Check if the file exists, and delete if it does
if (file.exists(pdf_output)) {
  file.remove(pdf_output)
}
[1] TRUE
# Now combine the PDFs into a new file
pdf_files <- list.files(figures_folder, pattern = "\\.pdf$", full.names = TRUE)
qpdf::pdf_combine(input = pdf_files, output = pdf_output)
[1] "data/outputs/CFUs/figures/HNOBac_SummaryCFUs.pdf"
Cell Counts
LDH
Source Code
---
execute:
  message: FALSE
  warning: FALSE
---

# CFUs {.unnumbered}

```{r}
library(tidyverse)
library(ggpubr)
library(ggtext)
library(scales)
library(lme4)
library(afex)
library(emmeans)
library(gridExtra)
```

## Data Input and Selection

### File Paths

```{r}
# Folder paths
input_path <- "data/input_data/CFUs/"
metadata_path <- "data/metadata/CFUs"

# Create subfolders for output files
dataframes_folder <- "data/dataframes"
if (!file.exists("data/dataframes")) {
  dir.create("data/dataframes", recursive = TRUE)
}

# Load data and metadata
input_data <- read_csv(file.path(input_path, "HNOBac_CFUs_0130_2024.csv")) %>% mutate_if(is.character, factor)
input_data$Time <- as.factor(input_data$Time)
Bac_order <- read_csv(file.path(metadata_path, "Order_Bacteria_CFUs.csv"))
```

### Data clean-up

```{r}
# Setting zero values to the limit of detection
CFU_data <- input_data %>%
  mutate(
    LOD = CFUs == 0,
    NewCFU = ifelse(LOD, 3.75, CFUs)
  )

# Factor Ordering and Styling
CFU_data <- CFU_data %>%
  mutate(Combined = interaction(bacteria, Time))
CFU_data <- merge(CFU_data, Bac_order, by = "Combined") 
CFU_data$bacteria_label <- factor(CFU_data$bacteria_label, levels = Bac_order$bacteria_label)
CFU_data$Line <- fct_recode(CFU_data$Line, "HNO918" = "A", "HNO204" = "B", "HNO919" = "C") 
```

### Saving files

```{r}
# Save data frame as CSV files in the output folder
write_csv(CFU_data, file.path(dataframes_folder, "CFU_values.csv"))

# Save data frame as R objects in the output folder
saveRDS(CFU_data, file.path(dataframes_folder, "CFU_values.rds"))

# Cleaning-up all objects from the environment
rm(list = ls())

# Use this to read the final objects
CFU_data <- readRDS("data/dataframes/CFU_values.rds")
```

## Stats and Plots

### File Paths

```{r}
# Folder paths
dataframes_path <- "data/dataframes"
metadata_path <- "data/metadata/CFUs"

# Create subfolders for output files
figures_folder <- "data/outputs/CFUs/figures"
if (!file.exists("data/outputs/CFUs/figures")) {
  dir.create("data/outputs/CFUs/figures", recursive = TRUE)
}
stats_folder <- "data/outputs/CFUs/stats"
if (!file.exists("data/outputs/CFUs/stats")) {
  dir.create("data/outputs/CFUs/stats", recursive = TRUE)
}

# Load data and metadata
CFU_data <- readRDS("data/dataframes/CFU_values.rds")
Bac_order <- read_csv(file.path(metadata_path, "Order_Bacteria_CFUs.csv"))
```

### Function for each temp condition

```{r, warning = FALSE}
# Function to analyze each temp condition
analysis_function <- function(data, each_temp, cutoff_pvalue, cutoff_FC) {
  
  # Subset the data to the selected temp
  data_subset <- data %>%
    filter(Temp == each_temp) 
  
  # Remove time 0h from the stats
  data_stats <- data_subset %>%
    filter(Time != 0)
  
  # Mixed-effects model with random effects
  model <- lmer(log(NewCFU) ~ bacteria * Time 
                + (1|Line) + (1|Line:Date), 
                data = data_stats)
  #Anova
  anova <- anova(model)
  anova_df <- as.data.frame(anova) %>%
    mutate(sign = case_when(
      `Pr(>F)` < cutoff_pvalue ~ "*",
      TRUE ~ "")) %>%
    mutate_if(is.numeric, ~ format(., digits = 2, scientific = TRUE))
  
  # Calculate Individual contrasts
  emmeans_model <- emmeans(model, ~ bacteria * Time)
  emmeans_time <- pairs(emmeans_model, simple = "Time", adjust = "none")    
  
  # Extract random effects and convert to dataframe (if not singular)
  random_effects_df <- as.data.frame(VarCorr(model)) %>%
    mutate(proportion = round(100 * (vcov / sum(vcov)), 2))
  
  # Adds predictions based on fixed effects, averaged over random effects. It gives a population estimate
  data_stats <- cbind(data_stats, predval = predict(model,re.form = NA, se.fit = TRUE))
  data_summary_df <- data_stats %>%
    group_by(Combined, bacteria_label) %>%
    summarize(mean.real = mean(NewCFU),
              mean.predval = mean(predval.fit), 
              mean.predval.se = mean(predval.se.fit)) %>%
    mutate(exp.mean.predval = exp(mean.predval),
           max = exp(mean.predval + 2*mean.predval.se),
           min = exp(mean.predval - 2*mean.predval.se))
  
  # Extract time contrasts from emmeans_model, convert to dataframe and adjust pvalues
  contrasts_time_df <- as.data.frame(summary(emmeans_time)) %>%
    mutate(Temp = each_temp) %>%
    mutate(p.adj.holm = p.adjust(p.value, method = "holm")) %>%
    mutate(sign = case_when(
      p.adj.holm < cutoff_pvalue ~ "*",
      TRUE ~ ""))
  
  # Edits to the contrast dataframe to include pvalue brackets in plot
  contrasts_time_df <- contrasts_time_df %>%
    separate(contrast, into = c("Time1", "Time2"), sep = " - ") %>%
    mutate(Time1 = sub("Time", "", Time1),
           Time2 = sub("Time", "", Time2)) %>%
    mutate(condition1 = paste(bacteria, Time1, sep = "."),
           condition2 = paste(bacteria, Time2, sep = "."))
  
  contrasts_time_df$group1 <- Bac_order$bacteria_label[match(contrasts_time_df$condition1, Bac_order$Combined)]
  contrasts_time_df$group2 <- Bac_order$bacteria_label[match(contrasts_time_df$condition2, Bac_order$Combined)]
  
  # Calculate fold-change values for each contrast
  contrasts_time_df <- contrasts_time_df %>%
    ungroup() %>%
    left_join(select(data_summary_df, Combined, exp.mean.predval), by = join_by(condition1 == Combined)) %>%
    left_join(select(data_summary_df, Combined, exp.mean.predval), by = join_by(condition2 == Combined), suffix = c(".1", ".2")) %>%
    mutate(FC = exp.mean.predval.1 / exp.mean.predval.2,
           FC = if_else(FC < 1, -1 / FC, FC),
           highlighted = case_when(
             FC <= -cutoff_FC ~ "+",
             FC >= cutoff_FC ~ "-",
             TRUE ~ "")) 
  
  # Select p values to plot and define their location
  contrast_sign <- contrasts_time_df %>%
    filter(sign != "" & highlighted != "") %>%
    mutate(p.adj.holm = format(p.adj.holm, digits = 2, scientific = TRUE))
  
  location <- log10(max(data_subset$NewCFU, na.rm = TRUE)) * 1.1
  
  # Standard Boxplot
  plot_1 <- ggplot() +
    geom_boxplot(data = data_subset, aes(x = bacteria_label, y = NewCFU, fill = bacteria_label)) + 
    
    geom_jitter(data = data_subset, aes(x = bacteria_label, y = NewCFU, shape = Line), 
                fill = "grey50", color = "grey30", size = 2, width = 0.05, stroke = 0.75) +
    
    scale_fill_manual(values = c("#AA35E3","#AA35E3","#AA35E3",
                                 "#2e67f2","#2e67f2","#2e67f2", 
                                 "#927ed1","#927ed1","#927ed1")) +
    
    scale_shape_manual(values = c(21, 22, 24)) +
    
    scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
                  labels = trans_format("log10", math_format(10^.x))) +
    labs(x = "Hours post-inoculation",
         y = paste0("CFUs/HNO at ", each_temp, " °C")) +
    theme_bw() +
    theme(panel.grid = element_blank(),
          legend.position = "none",
          text = element_text(size = 20), 
          axis.text.x = element_markdown(), 
          axis.text.y = element_text(color = "black"))
  
  # Plot with predicted means and standard errors of the estimates
  plot_2 <- ggplot() +
    geom_point(data = data_subset, 
                aes(x = bacteria_label, y = NewCFU, fill = bacteria_label, color = bacteria_label, shape = Line, group = Line), 
                position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.2),
                size = 1.5, alpha = 0.75, stroke = 0.75) +

    geom_point(data = data_summary_df, aes(x = bacteria_label, y = exp.mean.predval), shape = 3, size = 3) +
    geom_errorbar(data = data_summary_df, aes(x = bacteria_label,
                                              y = exp.mean.predval,
                                              ymax = max,
                                              ymin = min),
                  width = 0.5) +
    
    scale_fill_manual(values = c("#AA35E3","#AA35E3","#AA35E3","#2e67f2","#2e67f2","#2e67f2","#927ed1","#927ed1","#927ed1")) +
    scale_color_manual(values = c("#AA35E3","#AA35E3","#AA35E3","#2e67f2","#2e67f2","#2e67f2","#927ed1","#927ed1","#927ed1")) +
    scale_shape_manual(values = c(21, 22, 24)) +
    
    scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
                  labels = trans_format("log10", math_format(10^.x)),
                  expand = c(0.1,0)) +
    
    labs(x = "Hours post-inoculation",
         y = paste0("CFUs/HNO at ", each_temp, " °C")) +
    theme_bw() +
    theme(panel.grid = element_blank(), 
          legend.position = "none",
          text = element_text(size = 20), 
          axis.text.x = element_markdown(), 
          axis.text.y = element_text(color = "black"))
  
  # Conditionally add p-value annotations layer
  if (nrow(contrast_sign) > 0) {
    plot_2 <- plot_2 +
      stat_pvalue_manual(contrast_sign, label = "p.adj.holm", y.position = location,
                         tip.length = 0.02, bracket.shorten = 0.2, vjust = -0.2, bracket.size = 0.3, size = 3.5)
  } else {
    plot_2 <- plot_2
  }
  
  # Arrange plot and tables for summary pdf
  table <- contrasts_time_df %>%
    select(condition1, condition2, p.adj.holm, sign, exp.mean.predval.1, exp.mean.predval.2, FC, highlighted) %>%
    mutate(p.adj.holm = format(p.adj.holm, digits = 2, scientific = TRUE))
  
  Tmin <- ttheme_minimal()
  panel <- ggarrange(plot_1 + theme(plot.margin = unit(c(0.25,0.25,0.25,0.25), "in")), 
                     plot_2 + theme(plot.margin = unit(c(0.25,0.25,0.25,0.25), "in")),
                     tableGrob(anova_df, theme = Tmin), 
                     tableGrob(random_effects_df, theme = Tmin, rows = NULL), 
                     tableGrob(table, theme = Tmin, rows = NULL), 
                     ncol = 1, heights = c(0.7, 0.7, 0.2, 0.2, 0.2),
                     labels = c("  Standard Boxplot ", "Predicted Mean ± 2*SE", "    Anova    ", "Random Effects", "   Contrasts  "))
  panel <- annotate_figure(panel, top = text_grob(
    paste0("Analysis for ", each_temp, "C. P-value: ", cutoff_pvalue, " and FC: ", cutoff_FC),
                                                         face = "bold", size = 14, color = "red"))
  
  # Save files
  ggsave(panel, filename = paste0(figures_folder, "/summaryCFU_", each_temp, ".pdf"), width = 10, height = 15)
  ggsave(plot_2, filename = paste0(figures_folder, "/plotCFU_", each_temp, ".png"), width = 7, height = 6)
  saveRDS(plot_2, file.path(figures_folder, paste0("plotCFU_", each_temp, ".rds")))
  write_csv(anova_df, file.path(stats_folder, paste0("anova_", each_temp, ".csv")))
  write_csv(random_effects_df, file.path(stats_folder, paste0("stats_random_effects_", each_temp, ".csv")))
  write_csv(contrasts_time_df, file.path(stats_folder, paste0("stats_contrasts_", each_temp, ".csv")))
  write_csv(data_summary_df, file.path(stats_folder, paste0("stats_summary_", each_temp, ".csv")))
  
  return(list(
    anova = anova_df,
    random_effects = random_effects_df,
    contrasts_time = contrasts_time_df,
    data_summary = data_summary_df,
    data_stats = data_stats,
    plot_1 = plot_1,
    plot_2 = plot_2,
    panel = panel
  ))
}
```

### Apply to each temp

#### Main Data: 34C

```{r}
#| warning: FALSE
analysis_function(CFU_data, each_temp = "34", cutoff_pvalue = 0.05, cutoff_FC = 1)
```

#### Supplemental Data: 37C

```{r}
#| warning: FALSE
analysis_function(CFU_data, each_temp = "37", cutoff_pvalue = 0.05, cutoff_FC = 1)
```

#### Merged Files

```{r}
pdf_output <- file.path(figures_folder, "HNOBac_SummaryCFUs.pdf")

# Check if the file exists, and delete if it does
if (file.exists(pdf_output)) {
  file.remove(pdf_output)
}

# Now combine the PDFs into a new file
pdf_files <- list.files(figures_folder, pattern = "\\.pdf$", full.names = TRUE)
qpdf::pdf_combine(input = pdf_files, output = pdf_output)
```